package br.ufrj.dcc.trabxml;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.rpc.ServiceException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import br.ufrj.dcc.trabxml.manager.BookManager;
import br.ufrj.dcc.trabxml.manager.XmlManager;
import br.ufrj.dcc.trabxml.util.EXistConnection;
import br.ufrj.dcc.trabxml.util.Properties;
import br.ufrj.dcc.trabxml.util.TrabUtil;
import br.ufrj.dcc.trabxml.util.XmlUtil;

public class RequestProcessor {
    
    public static void processRequest(String xml) throws DOMException, XPathExpressionException, UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException, ServiceException {
        if (XmlManager.isCatalogRequest(xml)) {
            processCatalogRequest(xml);
        } else if (XmlManager.isLendOrReturnRequest(xml)) {
            processLendOrReturnRequest(xml);
        }
    }
    
    public static void processLendOrReturnRequest(String xml) throws UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException, DOMException, XPathExpressionException {
        Node root = XmlUtil.getDocumentRoot(xml);
        XPath xpath = XPathFactory.newInstance().newXPath();        
        final String id = ((Node) xpath.evaluate("@id", root,
                XPathConstants.NODE)).getNodeValue();
        final NodeList requests = (NodeList)xpath.evaluate("//livro/..",root,XPathConstants.NODESET);
        String response = null;
        String mygroup = Properties.instance.getProperty("mygroup");
        int theSender = 0;
        for(int i = 0; i < requests.getLength(); i++) {
            Node request = requests.item(i);
            final String _sender = ((Node) xpath.evaluate("de/text()", request,
                    XPathConstants.NODE)).getNodeValue();
            final String _receiver = ((Node) xpath.evaluate("para/text()", request,
                    XPathConstants.NODE)).getNodeValue();
            final int sender = Integer.parseInt(_sender);
            if (!_receiver.equals(mygroup)) {
                continue;
            }
            if (response == null) {
                theSender = sender;
                response = "<mensagem id=\""+id+"\" remetente=\""+mygroup+"\" destinatario=\""+sender+"\"><respostas>";
            }            
            final String _owner = ((Node) xpath.evaluate("livro/dono/text()", request,
                    XPathConstants.NODE)).getNodeValue();
            final String isbn = ((Node) xpath.evaluate("livro/isbn/text()", request,
                    XPathConstants.NODE)).getNodeValue();            
            final int owner = Integer.parseInt(_owner);
            BookManager manager = new BookManager();            
            if (request.getNodeName().equals("emprestimo")) {
                boolean resp = manager.lendMyBook(sender,owner,isbn);
                response += "<resposta><codigo>"+(resp?"1":"2")+"</codigo><livro><isbn>"+isbn+"</isbn><dono>"+owner+"</dono></livro></resposta>";
            } else if (request.getNodeName().equals("devolucao")) {
                try {
                    manager.acceptBookReturn(sender, owner, isbn);
                    response += "<resposta><codigo>3</codigo><livro><isbn>"+isbn+"</isbn><dono>"+owner+"</dono></livro></resposta>";
                } catch (Exception e) {
                    System.out.println("Erro ao processar devolucao. O grupo "+sender+" enviou um pedido invalido.");
                }
            }
        }
        if (response != null) {
            response += "</respostas></mensagem>";
            MySender.sendBack(TrabUtil.getGroupHost(theSender), TrabUtil.getGroupPort(theSender), response);
        }
    }
      
    public static void processCatalogRequest(String xml) throws DOMException, XPathExpressionException, UnsupportedEncodingException, ParserConfigurationException, SAXException, IOException, ServiceException {
        Node root = XmlUtil.getDocumentRoot(xml);
        XPath xpath = XPathFactory.newInstance().newXPath();        
        /*final String id = ((Node) xpath.evaluate("@id", root,
                XPathConstants.NODE)).getNodeValue();*/
        final String _sender = ((Node) xpath.evaluate("@remetente", root,
                XPathConstants.NODE)).getNodeValue();
        final String _receiver = ((Node) xpath.evaluate("@destinatario", root,
                XPathConstants.NODE)).getNodeValue();
        final int sender = Integer.parseInt(_sender);
        if (!_receiver.equals(Properties.instance.getProperty("mygroup"))) {
            return;
        }
        EXistConnection conn = new EXistConnection();        
        conn.connect();
        try {
            Node node = (Node)xpath.evaluate("solicitacao/@tipo", root,XPathConstants.NODE);
            if (node != null) {
                if (node.getNodeValue().equals("catalogo")) {
                    String response = conn.gainFile(BookManager.MY_CATALOG);
                    MySender.sendBack(TrabUtil.getGroupHost(sender), TrabUtil.getGroupPort(sender), response);
                }
            }
        } finally {
            conn.disconnect();
        }
    }
    

}
